﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using System.Collections.Specialized;

namespace OpenLinkCommon.UnitTest.Collections
{
    using Windy.OpenLink;
    using Windy.OpenLink.Collections;
    using Windy.OpenLink.Contracts;

    public class NameCollectionTest
    {
        private void SequenceEqual<T>(IEnumerable<T> expected, IEnumerable<T> actual)
        {
            Assert.Equal(expected.ToArray(), actual.ToArray());
        }

        [Fact()]
        public void OwnerTest()
        {
            NameCollection<NameCollectionTest> test;

            test = new NameCollection<NameCollectionTest>(this);

            Assert.Equal(this, test.Owner);
            Assert.Equal(this, (test as IOwnerableObject).Owner);

            test = new NameCollection<NameCollectionTest>(this, "a", "b", "c", "d");
            Assert.Equal(this, test.Owner);
            Assert.Equal(this, (test as IOwnerableObject).Owner);
            Assert.Equal(4, test.Count);
            Assert.Equal<IEnumerable<string>>(new string[] { "a", "b", "c", "d" }, test.ToArray());
        }

        [Fact()]
        public void BasicFunctionTest()
        {
            NameCollection<NameCollectionTest> test = new NameCollection<NameCollectionTest>(this);

            var names = "aa,bb,cc,dd,ee".Split(',').ToList();
            List<string> notified = new List<string>();

            test.CollectionChanged += (o, e) =>
                {
                    switch (e.Action)
                    {
                        case NotifyCollectionChangedAction.Add:
                            var newItems = e.NewItems.Cast<string>();
                            notified.Add(newItems.First());
                            break;
                        case NotifyCollectionChangedAction.Remove:
                            var oldItems = e.OldItems.Cast<string>();
                            notified.Remove(oldItems.First());
                            break;
                        case NotifyCollectionChangedAction.Reset:
                            notified.Clear();
                            break;
                        default:
                        case NotifyCollectionChangedAction.Move:
                        case NotifyCollectionChangedAction.Replace:
                            Assert.True(false, "Unexpected CollectionChangeAction");
                            break;
                    }
                };

            test.AddRange(names);
            SequenceEqual(names, test);
            SequenceEqual(names, notified);

            Assert.False(test.Add("aa"));
            SequenceEqual(names, test);
            SequenceEqual(names, notified);
            Assert.True(test.Add("qq"));
            Assert.Contains("qq", test);
            Assert.Contains("qq", notified);
            Assert.Equal(names.Count + 1, test.Count);
            Assert.True(test.Remove("qq"));
            SequenceEqual(names, test);
            SequenceEqual(names, notified);

            test.Clear();
            Assert.Empty(test);
            Assert.Empty(notified);
        }






    }
}
